/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#include "../import/head.h"
#include "../macro/head.h"
#include "aio_epoll_notify.h"
#include "aio_thread.h"
#include "aio_helper.h"
#include "aio_impl.h"
#include "head.h"

/////////////////////////////////////////////////////////////////////////////////////////
// 
namespace xos_aio
{
    //////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    static aio_impl::ITEM_DATA xos_item_data;

    //////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    aio_impl::aio_impl()
    {
        m_pEpollNotify = 0;
        m_nEpollSize = 256;
        m_pAioThread = 0;
        m_pCallback = 0;
        m_hEpoll = -1;
        m_nTimeout = -1;
    }

    aio_impl::~aio_impl()
    {
        term();
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    int aio_impl::get_xos_item_data( ITEM_DATA*& item_ptr )
    {
        int ret = 0;
        xos_item_data.set_container( mgr::container() );
        item_ptr = &xos_item_data;
        return ret;
    }

    int aio_impl::notify( xos_box::i_msg *& pMsg )
    {
        int ret = 0;
        m_pCallback->notify( pMsg );
        return ret;
    }

    int aio_impl::init()
    {
        int nRet = 0;

        if( 0 == nRet )
        {
            m_hEpoll = epoll_create( m_nEpollSize );

            if( -1 == m_hEpoll )
            {
                nRet = 1;
            }
        }

        if( 0 == nRet )
        {
            m_pAioThread = new aio_thread( this );
            m_pAioThread->init();
        }

        if( 0 == nRet )
        {
            m_pEpollNotify = new aio_epoll_notify( this );
            nRet = m_pEpollNotify->init();
        }

        return nRet;
    }

    int aio_impl::term()
    {
        int nRet = 0;

        if( m_pAioThread )
        {
            m_pAioThread->term();
            delete m_pAioThread;
            m_pAioThread = 0;
        }

        if( m_pEpollNotify )
        {
            m_pEpollNotify->term();
            delete m_pEpollNotify;
            m_pEpollNotify = 0;
        }

        if( -1 != m_hEpoll )
        {
            close( m_hEpoll );
            m_hEpoll = -1;
        }

        xos_stl::release_interface( m_pCallback );

        m_request_list.put_back_to_pool();
        m_closing_list.put_back_to_pool();

        return nRet;
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    // 
    // set callback. 
    // 
    int aio_impl::set_callback( xos::f_runnable pCallback )
    {
        int ret = 0;
        if( !m_pCallback )
        {
            m_pCallback = mgr::get()->notify()->clone();
        }
        m_pCallback->set_callback( pCallback );
        return ret;
    }

    // 
    // m_bData[0] : true or false for result
    // 
    // m_nMsg[0]  : cmd type
    // m_nData[1] : local port
    // m_szStr[1] : local ip
    // 
    // m_lpData[0] : UserKey
    // m_lpData[1] : AioKey
    // 
    int aio_impl::post_request( xos_box::i_msg *& pMsg )
    {
        int nRet = 0;
        m_pEpollNotify->notify( pMsg );
        return nRet;
    }

} // xos_aio
